﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace BaiDuSitemap.Edit
{
    public partial class ucSnapShot : UserControl
    {
        #region Attributes

        private Thread myThread = null;
        private static ManualResetEvent Threadmre = new ManualResetEvent(true);
        private delegate DataGridViewRowCollection myDeleGategetDataGridView();
        private delegate string myDeleGategetDataGridViewCount();
        private delegate void myDeleGateupdateDataGridViewRow(DataGridViewRow row, string snapDate, string checkDate);
        private delegate void myDeleGateSetButton(bool b);
        private delegate void myDeleGateSetProgress(bool b, string s, int index, int count);
        private bool isPause = false;

        private Regex regex = new Regex(@"\d{4}-\d{1,2}-\d{1,2}");
        private string DefaultShot = "未收录";

        #endregion

        public ucSnapShot()
        {
            InitializeComponent();
            this.pProgress.BackColor = Color.FromArgb(5, 0, 0, 0);
        }

        private void ucSnapShot_Load(object sender, EventArgs e)
        {
            InitComboBox(0);
        }

        private void ucSnapShot_SizeChanged(object sender, EventArgs e)
        {
            this.picClose.Location = new Point(this.Width - this.picClose.Width - 3, 3);
            Point p = new Point();
            p.X = (this.Width - this.pProgress.Width) / 2;
            p.Y = (this.Height - this.pProgress.Height) / 2;
            this.pProgress.Location = p;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.statusStrip1.BackColor = Sitemap.AeroColor;
        }

        #region Event

        #region Button

        private void btnCheck_MouseEnter(object sender, EventArgs e)
        {
            ShowTip(true, "检查URL地址是否被收录，已收录的URL不进行检查", this.PointToClient(Control.MousePosition));
        }

        private void btnCheck_MouseMove(object sender, MouseEventArgs e)
        {
            //ShowTip(true, "检查URL地址是否被收录，已收录的URL不进行检查", this.PointToClient(Control.MousePosition));
        }

        private void btnCheck_MouseLeave(object sender, EventArgs e)
        {
            ShowTip(false,"",new Point(0,0));
        }

        private void btnCheck_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("正在进行快照检查，请等待操作完成");
                return;
            }

            cbbGroup_SelectedIndexChanged(sender, e);

            myThread = new Thread(new ThreadStart(ThreadCheckSnapShot));
            myThread.Start();
        }

        private void btnFullCheck_MouseEnter(object sender, EventArgs e)
        {
            ShowTip(true, "检查全部URL地址是否被收录，已收录的URL会重新进行检查", this.PointToClient(Control.MousePosition));
        }

        private void btnFullCheck_MouseMove(object sender, MouseEventArgs e)
        {
            //ShowTip(true, "检查全部URL地址是否被收录，已收录的URL会重新进行检查", this.PointToClient(Control.MousePosition));
        }

        private void btnFullCheck_MouseLeave(object sender, EventArgs e)
        {
            ShowTip(false, "", new Point(0, 0));
        }

        private void btnFullCheck_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("正在进行快照检查，请等待操作完成");
                return;
            }

            cbbGroup_SelectedIndexChanged(sender, e);

            myThread = new Thread(new ThreadStart(ThreadFullCheckSnapShot));
            myThread.Start();
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            if (isPause)
            {
                Threadmre.Set();
                isPause = false;
                this.btnPause.Text = "暂停";
            }
            else
            {
                Threadmre.Reset();
                isPause = true;
                this.btnPause.Text = "继续";
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在检查快照，确认要取消吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
                SetButton(false);
                this.btnPause.Text = "暂停";
                SetProgress(false, "", 0, 0);
            }
        }

        #endregion

        #region PictureBox

        private void picClose_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行网址快照检查，确认要关闭吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }

                myThread.Abort();
            }

            this.Dispose();
        }

        private void picClose_MouseEnter(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close02;
        }

        private void picClose_MouseLeave(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close01;
        }

        #endregion

        #region ComboBox

        private void cbbGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cbbGroup.SelectedIndex == 0) return;

            DataTable dt = DBO.URL.get4SnapShot(int.Parse(this.cbbGroup.SelectedValue.ToString()));

            this.dgvURL.AutoGenerateColumns = false;
            this.dgvURL.Columns[0].DataPropertyName = "url";
            this.dgvURL.Columns[1].DataPropertyName = "gname";
            this.dgvURL.Columns[2].DataPropertyName = "snapshot";
            this.dgvURL.Columns[3].DataPropertyName = "checkdate";
            this.dgvURL.DataSource = dt;
        }

        #endregion

        #region DataGridView

        private void dgvURL_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            this.tsslMsg.Text = string.Format("网址总数：{0}，快照总数：{1}", this.dgvURL.RowCount,DBO.URL.get4SnapShotCount(int.Parse(this.cbbGroup.SelectedValue.ToString())));
        }

        private string URI = DBO.Setting.Get("URI");

        private void dgvURL_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (e.RowIndex < 0) return;

                if (e.ColumnIndex == 2)
                {
                    if ((this.dgvURL.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == DefaultShot) || (string.IsNullOrEmpty(this.dgvURL.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString())))
                    {
                        if (MessageBox.Show("系统检测到该地址没有快照，确认要查看吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return;
                    }

                    Process.Start(string.Format(URI, this.dgvURL.Rows[e.RowIndex].Cells[0].Value.ToString()));
                }

                if (e.ColumnIndex == 0)
                {
                    Process.Start(this.dgvURL.Rows[e.RowIndex].Cells[0].Value.ToString());
                }
            }
        }

        #endregion

        #endregion

        #region Thread

        private void ThreadCheckSnapShot()
        {
            SetButton(true);

            int successed = 0;
            int failed = 0;
            int error = 0;
            int skip = 0;
            int hasDate = 0;

            int index = 0;
            int count = int.Parse(getDataGriedViewCount());
            int interval = int.Parse(DBO.Setting.Get("InterVal"));

            try
            {
                foreach (DataGridViewRow row in getDataGridView())
                {
                    Threadmre.WaitOne();
                    SetProgress(true, "正在检查快照。当前进度：{0}/{1}", index, count);
                    index++;

                    if (regex.IsMatch(row.Cells[2].Value.ToString()))
                    {
                        skip++;
                        continue;
                    }

                    string snapshot = Tools.Gather.getDate(row.Cells[0].Value.ToString());
                    int result = DBO.URL.Update4SnapShot(row.Cells[0].Value.ToString(), string.IsNullOrEmpty(snapshot) ? "0" : "1", snapshot, DateTime.Now.ToString());
                    if (!string.IsNullOrEmpty(snapshot)) hasDate++;
                    switch (result)
                    {
                        case -2:
                            error++;
                            break;
                        case 1:
                            successed++;
                            break;
                        default:
                            failed++;
                            break;
                    }

                    Threadmre.WaitOne();
                    updateDataGridViewRow(row, snapshot, DateTime.Now.ToString("yyyy-MM-dd"));

                    Thread.Sleep(interval * 1000);
                }

                Threadmre.WaitOne();
                SetProgress(false, "", 0, 0);
                MessageBox.Show(string.Format("检查完成。共检查{0}个地址（{1}个地址已收录），{4}个地址跳过，{2}个地址保存成功,{3}个地址保存失败，{5}个地址错误或未添加到数据库", index, hasDate, successed, failed, skip, error));
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
            }

            SetButton(false);
        }

        private void ThreadFullCheckSnapShot()
        {
            SetButton(true);

            int successed = 0;
            int failed = 0;
            int error = 0;
            int hasDate = 0;

            int index = 0;
            int count = int.Parse(getDataGriedViewCount());
            int interval = int.Parse(DBO.Setting.Get("InterVal"));

            try
            {
                foreach (DataGridViewRow row in getDataGridView())
                {
                    Threadmre.WaitOne();
                    SetProgress(true, "正在检查快照。当前进度：{0}/{1}", index, count);

                    string snapshot = Tools.Gather.getDate(row.Cells[0].Value.ToString());
                    int result = DBO.URL.Update4SnapShot(row.Cells[0].Value.ToString(), string.IsNullOrEmpty(snapshot) ? "0" : "1", snapshot, DateTime.Now.ToString());
                    if (!string.IsNullOrEmpty(snapshot)) hasDate++;
                    switch (result)
                    {
                        case -2:
                            error++;
                            break;
                        case 1:
                            successed++;
                            break;
                        default:
                            failed++;
                            break;
                    }
                    index++;
                    Threadmre.WaitOne();
                    updateDataGridViewRow(row, snapshot, DateTime.Now.ToString("yyyy-MM-dd"));

                    Thread.Sleep(interval * 1000);
                }

                Threadmre.WaitOne();
                SetProgress(false, "", 0, 0);
                MessageBox.Show(string.Format("检查完成。共检查{0}个地址（{1}个地址已收录），{2}个地址保存成功,{3}个地址保存失败，{4}个地址错误或添加到数据库", index, hasDate, successed, failed, error));
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
            }

            SetButton(false);
        }

        #endregion

        #region Method

        private void ShowTip(bool b, string s, Point p)
        {
            this.lblTip.Text = s;
            this.pTip.Width = this.lblTip.Width;
            this.pTip.Location = p;
            this.pTip.Visible = b;
            this.pTip.BringToFront();
        }

        private void InitComboBox(int index)
        {
            DataTable dt = DBO.Group.getAll();
            DataRow dr = null;
            dr = dt.NewRow();
            dr["gid"] = "-1";
            dr["gname"] = "--请选择--";
            dt.Rows.InsertAt(dr, 0);
            dr = dt.NewRow();
            dr["gid"] = "0";
            dr["gname"] = "--全部--";
            dt.Rows.InsertAt(dr, 1);

            this.cbbGroup.ValueMember = "gid";
            this.cbbGroup.DisplayMember = "gname";
            this.cbbGroup.DataSource = dt;
            this.cbbGroup.SelectedIndex = dt.Rows.Count - 1 < index ? 0 : index;
        }

        private DataGridViewRowCollection getDataGridView()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetDataGridView(getDataGridView)) as DataGridViewRowCollection;
            }
            else
            {
                return this.dgvURL.Rows;
            }
        }

        private string getDataGriedViewCount()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetDataGridViewCount(getDataGriedViewCount)) as string;
            }
            else
            {
                return this.dgvURL.RowCount.ToString();
            }
        }

        private void updateDataGridViewRow(DataGridViewRow row, string snapDate, string checkDate)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateupdateDataGridViewRow(updateDataGridViewRow), new object[] { row, snapDate, checkDate });
            }
            else
            {
                if (string.IsNullOrEmpty(snapDate)) row.DefaultCellStyle.ForeColor = Color.Red;
                row.Cells[2].Value = string.IsNullOrEmpty(snapDate) ? DefaultShot : snapDate;
                row.Cells[3].Value = checkDate;
            }
        }

        private void SetButton(bool b)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetButton(SetButton), new object[] { b });
            }
            else
            {
                this.btnPause.Enabled = b;
                this.btnCancel.Enabled = b;
            }
        }

        private void SetProgress(bool b,string s,int index,int count)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetProgress(SetProgress), new object[] { b, s, index, count });
            }
            else
            {
                this.pProgress.Visible = b;
                this.cbbGroup.Enabled = !b;
                this.pbProgress.Style = ProgressBarStyle.Blocks;
                this.pbProgress.Maximum = count;
                this.pbProgress.Value = index;
                this.lblMsg.Text = string.Format(s, index, count);
            }
        }

        public bool Closing()
        {
            if (myThread != null && myThread.IsAlive) return false;
            return true;
        }

        private bool getStatus()
        {
            if ((myThread != null && myThread.IsAlive) || this.pProgress.Visible) return false;
            return true;
        }

        #endregion
    }
}
